<?php

require_once 'Pfinal/config/PfinalConfigBase.class.php';
/**
 * 
 * @author yusaint
 * @since 2014-3-9
 * @project Pfinal
 */
class Pfinal {
	protected static $configInstance = null;
	
	/**
	 *
	 * @throws PFinalRuntimeException
	 */
	protected static function checkRuntimeStatus(){
		if (!defined('ROOT')){
			require_once 'Pfinal/exception/PfinalExceptionRuntime.class.php';
			throw new PFinal_Exception_Runtime('contant root dir is not defined');
		}
		
		if (!defined('CONTROLLER')) {
			require_once 'Pfinal/exception/PfinalExceptionRuntime.class.php';
			throw new PFinal_Exception_Runtime('contant root dir is not defined');
		}
	}
	
	/**
	 * 启动系统
	 * @param unknown_type $PfinalConfigPath
	 */
	public static function run($PfinalConfigPath){
		self::checkRuntimeStatus();
		self::initAutoload();
		self::$configInstance = self::loadConfigClass($PfinalConfigPath);		
		self::initSystem(self::$configInstance);
	}
	
	/**
	 * 
	 * @param Pfinal_Config_Base $configuration
	 */
	protected static function initSystem(Pfinal_Config_Base $configuration){
		require_once 'Pfinal/PfinalConfig.class.php';
		$kernelConfig = new PfinalConfig();
		$kernelConfig->configSystem($configuration);

		self::initPlugin($kernelConfig);
		//开启路由
		$router = self::initRoute($kernelConfig);
		//开启render,并且注入controller
		$render = self::initRender($kernelConfig);
		//开启分发
		$action = self::initDispatch($kernelConfig,$router);
		
		//self::initActiveRecord($kernelConfig);
		
		self::start($action, $render);
	}
	
	protected static function initActiveRecord(PfinalConfig $kernelConfig){
		//require_once 'Pfinal/PfinalModelAbstract.class.php';
	}
	
	/**
	 * 
	 * @param PfinalConfig $kernelConfig
	 */
	protected static function initPlugin(PfinalConfig $kernelConfig){
		$plugins = $kernelConfig->getPlugin()->getPlugins();
		foreach ($plugins as $plugin){
			$plugin->start();
		}
	}
	
	/**
	 * 
	 * @param Pfinal_Invocation_Handler $action
	 * @param PfinalRender $render
	 */
	protected static function start(Pfinal_Invocation_Handler $action,Pfinal_Render_Abstract $render){
		require_once 'Pfinal/PfinalHttpResponse.class.php';
		$httpResponse = new PfinalHttpResponse();
		$action->getInstance()->setHttpResponse($httpResponse);
		$interceptors = $action->getInstance()->getInterceptors();
		if (!empty($interceptors)){
			foreach ($interceptors as $interceptor){
				$interceptor->interceptor($action);
			}
		}else{
			$action->invoke();
			
			if (null === $action->getInstance()->getRender()){
				$rd = $render;
			}else{
				$rd = $action->getInstance()->getRender();
			}
			$rd->setHttpResponse($httpResponse);
			$rd->render();
		}
	}
	
	protected static function initAutoload(){
		require_once 'Pfinal/PfinalAutoloadLoader.class.php';
		spl_autoload_register(array('PfinalAutoloadLoader','systemAutoloader'));
	}
	
	/**
	 * 启动路由模块,router模块启动完成，转发给dispath模块，
	 * 在dispatch模块中完成interceptor plugin controller等核心功能
	 * @param PfinalConfig $kernelConfig
	 */
	protected static function initRoute(PfinalConfig $kernelConfig){
		require_once 'Pfinal/PfinalRouter.class.php';
		
		$kernelRouter = new PfinalRouter($kernelConfig);
		return $kernelRouter->dispatch();
	}
	
	/**
	 * 
	 * @param PfinalConfig $kernelConfig
	 * @param Pfinal_Route_Interface_Base $router
	 */
	protected static function initDispatch(PfinalConfig $kernelConfig,Pfinal_Route_Abstract $router){
		require_once 'Pfinal/PfinalDispatcher.class.php';
		$dispatcher = new PfinalDispatcher($kernelConfig, $router);
		return $dispatcher->loop();
	}
	
	
	protected static function initRender(PfinalConfig $kernelConfig){
		require_once 'Pfinal/PfinalRender.class.php';
		$render = new PfinalRender($kernelConfig);
		return $render->factory();
	}
	
	
	
	/**
	 * 
	 * @param unknown_type $PFinalConfigPath
	 * @throws PFinalRuntimeException
	 * @return PFinalConfig
	 */
	private static function loadConfigClass($PFinalConfigPath){
		if (is_null($PFinalConfigPath)||empty($PFinalConfigPath)){
			throw new Pfinal_Exception_Runtime("you must given the config class file path");
		}
		//loadConfig阶段，还未涉及到用户态代码，此时的autoload可以使用PFinal自带
		$namespace = explode('.',$PFinalConfigPath);
		$className = end($namespace);
		$path = implode(DIRECTORY_SEPARATOR, $namespace);
		$classPath = sprintf("%s%s%s.class.php",ROOT,DIRECTORY_SEPARATOR,$path);
		require_once $classPath;
		$instance = new $className();		
		if (!($instance instanceof Pfinal_Config_Base)){
			throw new Pfinal_Exception_Runtime("{$className} is not a valid PFinalConfig instance");
		}else{
			return $instance;	
		}
		
	}
}

?>